/*
* Copyright (c) 2021 Talkweb Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* mqtt 测试程序
*/

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

#include "tiot_state_api.h"
#include "tiot_sysdep_api.h"
#include "tiot_mqtt_api.h"
#include "cJSON.h"

extern tiot_sysdep_portfile_t g_tiot_sysdep_portfile;

static pthread_t g_mqtt_process_thread;
static pthread_t g_mqtt_recv_thread;
static uint8_t flag_mqtt_process_thread_running = 0;
static uint8_t flag_mqtt_recv_thread_running = 0;

int32_t test_print_logcb(int32_t code, char *message)
{
    printf("%s", message);
    return 0;
}

void test_mqtt_event_ctx(void *ctx, const tiot_mqtt_event_t *event, void *userdata)
{
    if(event->type==TIOT_MQTT_EVENT_CONNECT) {
        printf("TIOT_MQTT_EVENT_CONNECT\n");
    }
    else if(event->type==TIOT_MQTT_EVENT_RECONNECT) {
        printf("TIOT_MQTT_EVENT_RECONNECT\n");
    }
    else if(event->type==TIOT_MQTT_EVENT_DISCONNECT) {
        char *cause;
        if(event->data.disconnect == TIOT_MQTTDISCONNEVT_NETWORK_DISCONNECT) {
            cause="network disconnect";
        }
        else {
            cause="heartbeat disconnect";
        }
        printf("tiot_MQTTEVT_DISCONNECT: %s\n", cause);
    }
}

void test_mqtt_default_recv_ctx(void *ctx, const tiot_mqtt_recv_t *packet, void *userdata)
{
    if (packet->type == TIOT_MQTTRECV_HEARTBEAT_RESPONSE) {
        printf("heartbeat response\n");
    }
    else if(packet->type==TIOT_MQTTRECV_PUB){
        int res = 0;
        char *data = NULL;
        printf("pub, qos: %d, topic: %.*s\n", packet->data.pub.qos, packet->data.pub.topic_len, packet->data.pub.topic);
        printf("pub, payload: %.*s\n", packet->data.pub.payload_len, packet->data.pub.payload);
        res=tiot_mqtt_sub_recv_data(ctx, packet->data.pub.payload, &data);
        if (res>= 0) {
            printf("tiot_mqtt_sub successed\n");
        }
        else {
            printf("tiot_mqtt_sub failed, res: -0x%04X\n", -res);
            return;
        }
        printf("data:%s\n", data);
        g_tiot_sysdep_portfile.service_sysdep_free(data); 
    }
}


void *test_mqtt_process_thread(void *ctx)
{
    int32_t res = RET_SUCCESS;

    while(1) {
        sleep(1);
        res = tiot_mqtt_process(ctx);
        if (res != RET_USER_INPUT_EXEC_DISABLED) {}
        else {
            break;
        }
    }

    return NULL;
}

void *test_mqtt_recv_thread(void *ctx)
{
    int32_t res = RET_SUCCESS;

    while(1) {
         res = tiot_mqtt_recv(ctx);
        if(!flag_mqtt_recv_thread_running) {
            break;
        }
        if (res < RET_SUCCESS && res==RET_USER_INPUT_EXEC_DISABLED ) {
            break;
        }
    }
    
    return NULL;
}

int main(int argc, char *argv[])
{
    int32_t     res = RET_SUCCESS;
    void       *mq_process = NULL;
    int8_t      public_instance = 0;
    char       *url = "116.63.137.223";
    char        host[100] = {0};
    uint16_t    port = 1883;

    char *product_key       = "r0SPgcPsc";
    char *device_name       = "r0plgRlvR";
    char *device_secret     = "a57cdfc800205846";

    tiot_set_print_callback(test_print_logcb);
    tiot_sysdep_set_portfile(&g_tiot_sysdep_portfile);

    mq_process = tiot_mqtt_init();
    if (mq_process == NULL) {
        printf("tiot_mqtt_init failed\n");
        return -1;
    }

    if (1 == public_instance) {
        snprintf(host, 100, "%s.%s", product_key, url);
    } else {
        snprintf(host, 100, "%s", url);
    }

    tiot_mqtt_set_host(mq_process,host);
    tiot_mqtt_set_port(mq_process,&port);
    tiot_mqtt_set_product_key(mq_process,product_key);
    tiot_mqtt_set_device_name(mq_process,device_name);
    tiot_mqtt_set_device_secret(mq_process,device_secret);
    tiot_mqtt_recv_ctx(mq_process,test_mqtt_default_recv_ctx);
    tiot_mqtt_event_ctx(mq_process,test_mqtt_event_ctx);

    res = tiot_mqtt_connect(mq_process);
    if (res >= RET_SUCCESS) {
        printf("tiot_mqtt_connect successed\n");
    }
    else {
        tiot_mqtt_deinit(&mq_process);
        printf("tiot_mqtt_connect failed: -0x%04X\n", -res);
        return -1;
    }

    {
        res = tiot_mqtt_sub(mq_process, "persistent://T0001/default/r0SPgcPsc.r0plgRlvR.sys.event.propertyReport.post_reply", NULL, 1, NULL);
        //res = tiot_mqtt_sub(mq_process, "persistent://T0001/default/r0SPgcPsc.r0plgRlvR.sys.event.propertyReport.post", NULL, 1, NULL);
        //res = tiot_mqtt_sub(mq_process, "persistent://T0001/default/r0SPgcPsc.r0plgRlvR.sys.event.propertyReport.post", NULL, 1, NULL);
        //res = tiot_mqtt_sub(mq_process, "persistent://T0001/default/r0SPgcPsc.r0plgRlvR.sys.event.propertyReport.post_reply", NULL, 1, NULL);

    }

        char *pub_topic = "persistent://T0001/default/r0SPgcPsc.r0plgRlvR.sys.event.propertyReport.post";
        char *pub_payload = "{\"LightSwitch\":0,\"height\":100}";
        flag_mqtt_process_thread_running = 1;
        res = g_tiot_sysdep_portfile.service_task_create(&g_mqtt_process_thread, NULL, test_mqtt_process_thread, mq_process);
        if (res >= 0) {
            printf("pthread_create test_mqtt_process_thread successed\n");
        }
        else {
            printf("pthread_create test_mqtt_process_thread failed: %d\n", res);
            return -1;
        }

        flag_mqtt_recv_thread_running = 1;
        res = g_tiot_sysdep_portfile.service_task_create(&g_mqtt_recv_thread, NULL, test_mqtt_recv_thread, mq_process);
        if (res >= 0) {
            printf("pthread_create test_mqtt_recv_thread successed\n");
        }
        else {
            printf("pthread_create test_mqtt_recv_thread failed: %d\n", res);
            return -1;
        }

        while (1) {
            res = tiot_mqtt_pub_with_method(mq_process, pub_topic, (uint8_t *)pub_payload, (uint32_t)strlen(pub_payload), 0, "light");
            if (res >= 0) {
                printf("tiot_mqtt_sub successed\n");
            }
            else {
                printf("tiot_mqtt_sub failed, res: -0x%04X\n", -res);
                return -1;
            }
            sleep(2);
        }
    

    flag_mqtt_process_thread_running = 0;
    flag_mqtt_recv_thread_running = 0;
    sleep(1);
    res = tiot_mqtt_disconnect(mq_process);
    if (res >= RET_SUCCESS) {
        printf("tiot_mqtt_disconnect success\n");
    }
    else {
        tiot_mqtt_deinit(&mq_process);
        printf("tiot_mqtt_disconnect failed: -0x%04X\n", -res);
        return -1;
    }

    res = tiot_mqtt_deinit(&mq_process);
    if (res >= RET_SUCCESS) {
        printf("tiot_mqtt_deinit successed\n");
    }
    else {
        printf("tiot_mqtt_deinit failed: -0x%04X\n", -res);
        return -1;
    }

    g_tiot_sysdep_portfile.service_task_join(&g_mqtt_process_thread, NULL);
    g_tiot_sysdep_portfile.service_task_join(&g_mqtt_recv_thread, NULL);

    return 0;
}

